fix(cors): allow X-Cryptify-Source in browser preflights#189
Merged
Conversation
Contributor
Author
|
/dobby fix conflicts |
Contributor
There was a problem hiding this comment.
✅ Approved — clean, well-scoped CORS fix.
Reviewed against the Review-Dobby findings (none) and a per-rule compliance sweep (Haiku sub-agents over the applicable rules). No findings from either pass.
Highlights:
- Root cause correctly identified:
X-Cryptify-Source(postguard-website#228) rode into the preflight'sAccess-Control-Request-Headersbut was missing fromrocket_cors'allowed_headers, so the preflight 403'd without anAccess-Control-Allow-Origin. build_cors()extracted and shared by the production launch path and the test harness — this collapses the duplicated test-local CORS config that let the regression slip through, which is the real fix here.- Regression test preflights
POST /fileupload/initwithX-Cryptify-Sourceand asserts it's advertised inAccess-Control-Allow-Headers— matches the cryptify test-harness conventions (#[rocket::async_test], per-test uuid tempdata_dir, cleanup). - Conventional-commit title, tests-on-fixes, and fmt/clippy all satisfied (CI: 120 passed, clippy + fmt clean).
No ops changes needed since the allow-list isn't ops-templated; staging picks it up on the next edge image build. 👍
The website tags its uploads with X-Cryptify-Source for per-channel metrics (postguard-website#228), but the header was never added to the CORS allow-list. Browsers include it in the preflight's Access-Control-Request-Headers, rocket_cors rejects the preflight with a 403 carrying no Access-Control-Allow-Origin, and uploads from the website fail before they start. Staging hits this directly; production only works because its nginx answers preflights itself. Add the header to the allow-list, and extract build_cors() so the preflight smoke tests exercise the production CORS config instead of a test-local copy — the duplicated config is why the existing smoke test couldn't catch this regression.
rubenhensen
force-pushed
the
fix/cors-allow-x-cryptify-source
branch
from
July 14, 2026 11:55
41dda25 to
0d6be9a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Uploads from the staging website fail with
CORS Missing Allow Originon theOPTIONS /fileupload/initpreflight.Since encryption4all/postguard-website#228 the website sends
X-Cryptify-Source: websiteon every pg-js request so cryptify can attribute traffic per channel. Cryptify consumes that header inmetrics.rs, but it was never added to the CORSallowed_headerslist. Browsers include it in the preflight'sAccess-Control-Request-Headers,rocket_corsrejects the preflight with a 403 that carries noAccess-Control-Allow-Origin, and the browser blocks the upload before it starts.Verified against the live servers: the preflight with
x-cryptify-sourcegets 403 without CORS headers on staging, and a clean 204 without the header. Production is unaffected only because its nginx answers preflights itself (and mirrors requested headers) — therocket_corsconfig isn't exercised there.Fix
X-Cryptify-Sourceto the CORSallowed_headerslist.build_cors()and use it from both the production launch path and the test harness. The existing preflight smoke test asserted against a test-local copy of the CORS config, which is exactly why this regression went undetected.POST /fileupload/initwithX-Cryptify-Sourceand asserts it is advertised inAccess-Control-Allow-Headers.Staging runs the
edgeimage tag, so it picks this up on the next image build + pod restart. No ops changes needed — the header allow-list is not part of the ops-templated config.